# from cmcc import parse_html
import asyncio
import json
import time

import aioredis
import motor
from phone import Phone

from baseHandler import init_logger
from util.ctcc2 import get_aliqr


async def pre_order(obj, conn):
    logger.info(obj)
    if time.time() - obj["time"] > 30:

        await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                     {"$set": {
                                         "orderstate": "1"
                                     }})
        return {"code": 1, "message": "提取超时"}
    await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                 {"$set": {
                                     "orderstate": "8"
                                 }})

    ### 归属地查询
    p = Phone()
    prov_res = p.find(obj['tel_number'])
    if prov_res:
        logger.info(prov_res)
        unused = await conn.sismember("unused_ctcc_prov", prov_res.get("province"))
        if unused:
            logger.info("%s交费不可用", prov_res.get("province"))
            return {"code": 1, "message": "不可交费"}

    # 取单
    is_login = False
    for _ in range(5):
        try:
            # pay_channel = data.get("pay_channel")
            # 提取账号
            if not is_login:
                user_data = await conn.rpop("ctcc_user", encoding='utf-8')
                if user_data:
                    user_obj = await db.cmcc_username.find_one({"username": user_data})
                    logger.info("下单|%s|%s|%s", user_data, obj['ordernumber'], obj["tel_number"])
                    cookies = user_obj.get('cookies')
                    if not cookies:
                        continue
                    is_login = True
                else:
                    return{'code': -1, 'message': "没有账号"}

            # 下单

            future = get_aliqr(obj["tel_number"], obj['amount'], cookies, conn)
            result = await asyncio.wait_for(future, timeout=60)

            # 失效单号剔除
            if "登录失效" == result.get('message', ""):
                is_login = False
                await db.cmcc_username.update_one({"username": user_data}, {"$set": {"cookies": None}})
                continue
            else:
                wx_url = result.get('qrcode')
                order_id = result.get('orderid')
                message = result.get("message")
                if wx_url:
                    pre_queue_name = "PRE_CTCC_%s_%s" % (supplier, obj['amount'])
                    obj.update(result)
                    obj.update({"userdata": user_data})
                    logger.info(pre_queue_name)

                    await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                                 {"$set": {
                                                           'wx_url': wx_url,
                                                           "orderstate": '8',
                                                           "orderid": order_id,
                                                           "pay_type": "wx_h5",
                                                            "message": message
                                                           }
                                                  })
                    await conn.lpush(pre_queue_name, json.dumps(obj))
                    pre_queue_size = await conn.llen(pre_queue_name)
                    logger.info(pre_queue_size)
                    break
                else:
                    orderstate = '1'
                    await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                                 {"$set": {"orderstate": orderstate, "message": message}})

        except Exception as e:
            logger.info("%s取单失败", obj["tel_number"])
            logger.error(e, exc_info=True)
            result = {"code": 2, 'message': "取单失败"}
            orderstate = '1'
            await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                         {"$set": {"orderstate": orderstate, "message": '取单失败'}})
            break

    if "登录失效" in result.get('messge', ""):
        pass
    else:
        await conn.lpush('ctcc_user', user_data)


async def periodic(supplier, amount):
    orderlist = await aioredis.create_redis(address=('localhost', 6379), loop=loop)
    order_pool = await aioredis.create_pool(
        ('localhost', 6379),
        minsize=1,
        maxsize=1)
    task_queue = []
    while True:
        try:
            pre_queue_name = "PRE_CTCC_%s_%s" % (supplier, amount)
            pre_queue_size = await orderlist.llen(pre_queue_name)
            pre_cmcc_queue_len_name = "pre_ctcc_queue_len_%s_%s" % (supplier, amount)
            pre_size = await orderlist.get(pre_cmcc_queue_len_name, encoding='utf-8')
            if pre_size:
                pre_size = int(pre_size)
            else:
                pre_size = 3

            for i in task_queue:
                if i.done():
                    task_queue.remove(i)

            if len(task_queue) > 10:
                logger.info("任务过多")
                await  asyncio.sleep(1)
                continue

            logger.info("当前队列%s长度%s, 设置长度%s", pre_queue_name, pre_queue_size, pre_size)
            if pre_queue_size < pre_size:
                queue_name = "ctcc_%s_%s" % (supplier, amount)
                with await order_pool as conn:
                    obj = await conn.brpop(queue_name, encoding='utf-8')
                    logger.info(obj)
                    # if not obj:
                    #     await asyncio.sleep(1)
                    #     continue
                    obj = json.loads(obj[1].replace("'", '"'))
                    # obj = json.loads(obj)
                    my_task = asyncio.Task(pre_order(obj, orderlist))
                    task_queue.append(my_task)
            else:
                await asyncio.sleep(1)

        except Exception as e:
            logger.info(e)
            await asyncio.sleep(5)
            continue
    else:
        orderlist.close()
        await orderlist.wait_closed()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()

    logger = init_logger('cmcc', '/app/log/cs_notify/pre_order_ctcc.log')

    supplier = 'M2018072714131532672011'
    task = asyncio.Task(periodic(supplier, '30'))
    task = asyncio.Task(periodic(supplier, '50'))
    task = asyncio.Task(periodic(supplier, '100'))
    client = motor.motor_tornado.MotorClient('mongodb://cs_user:cmcc5188@localhost:12018/cs_recharge')
    db = client.cs_recharge
    loop.run_forever()
